package xh.server;

/**
 * Created by Administrator on 2016/6/25.
 */

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.codec.http.DefaultFullHttpResponse;
import io.netty.handler.codec.http.FullHttpResponse;
import io.netty.handler.codec.http.HttpContent;
import io.netty.handler.codec.http.HttpRequest;
import xh.util.Global;
import xh.util.HttpUtils;

import java.net.URLDecoder;
import java.util.HashSet;
import java.util.Set;

import static io.netty.handler.codec.http.HttpHeaders.Names.LOCATION;
import static io.netty.handler.codec.http.HttpResponseStatus.FOUND;
import static io.netty.handler.codec.http.HttpVersion.HTTP_1_1;


public class HttpServerInboundHandler extends ChannelInboundHandlerAdapter {

    private HttpRequest request;

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg)
            throws Exception {
        if (msg instanceof HttpRequest) {

            String uri = URLDecoder.decode(((HttpRequest) msg).getUri(), Global.DefaultCharset.name());

            if (isIgnoreUrls(uri)) {
                request = null;
                ctx.channel().close();
            } else if (uri.length() == 0 || uri.equals("/")) {
                FullHttpResponse response = new DefaultFullHttpResponse(HTTP_1_1, FOUND);
                response.headers().set(LOCATION, "/statics/html/index.html");

                ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE);
            } else {
                request = (HttpRequest) msg;
                System.out.println("Uri:" + uri);
            }
        }


        if (msg instanceof HttpContent) {

            if (request == null) {
                return;
            }

            HttpContent content = (HttpContent) msg;
            ByteBuf buf = content.content();
            System.out.println(buf.toString(io.netty.util.CharsetUtil.UTF_8));


            RequestProcessor processor = ServerController.dispatcher().dispatch(request, content, ctx);

            if (processor == null) {
                FullHttpResponse response = HttpUtils._404();
                ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE);
            } else {
                FullHttpResponse response;
                try {
                    response = processor.process();
                } catch (Exception e) {
                    e.printStackTrace();

                    response = HttpUtils._500();
                }

                if (response != null) {
                    ctx.write(response);
                    ctx.flush();
                }
            }
        }
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        ctx.flush();
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        cause.printStackTrace();
        ctx.close();
    }

    private boolean isIgnoreUrls(String uri) {

        Set<String> s = new HashSet<String>();
        s.add("/favicon.ico");

        return s.contains(uri);
    }

}